"""
环境卫生管理相关的数据模型定义
"""
from datetime import datetime
from typing import List, Dict, Any, Optional, Tuple
from pydantic import BaseModel, Field, field_validator
from enum import Enum
import numpy as np


class WasteType(str, Enum):
    """垃圾类型枚举"""
    RECYCLABLE = "recyclable"  # 可回收垃圾
    HAZARDOUS = "hazardous"    # 有害垃圾
    WET = "wet"                # 湿垃圾/厨余垃圾
    DRY = "dry"                # 干垃圾
    PAPER = "paper"            # 纸类
    PLASTIC = "plastic"        # 塑料
    GLASS = "glass"            # 玻璃
    METAL = "metal"            # 金属
    ORGANIC = "organic"        # 有机垃圾
    ELECTRONIC = "electronic"  # 电子垃圾
    UNKNOWN = "unknown"        # 未知类型


class CleanlinessLevel(str, Enum):
    """清洁度级别枚举"""
    EXCELLENT = "excellent"    # 优秀 (90-100)
    GOOD = "good"             # 良好 (80-89)
    FAIR = "fair"             # 一般 (70-79)
    POOR = "poor"             # 较差 (60-69)
    VERY_POOR = "very_poor"   # 很差 (0-59)


class HygieneIssueType(str, Enum):
    """卫生问题类型枚举"""
    LITTER = "litter"                    # 乱扔垃圾
    OVERFLOWING_BIN = "overflowing_bin"  # 垃圾桶溢出
    SPILL = "spill"                      # 洒漏
    STAIN = "stain"                      # 污渍
    DUST = "dust"                        # 灰尘
    DEBRIS = "debris"                    # 碎屑
    GRAFFITI = "graffiti"               # 涂鸦
    DAMAGE = "damage"                    # 损坏
    PEST = "pest"                        # 害虫
    ODOR = "odor"                        # 异味


class CleaningTaskStatus(str, Enum):
    """清洁任务状态枚举"""
    PENDING = "pending"        # 待处理
    ASSIGNED = "assigned"      # 已分配
    IN_PROGRESS = "in_progress"  # 进行中
    COMPLETED = "completed"    # 已完成
    VERIFIED = "verified"      # 已验证
    CANCELLED = "cancelled"    # 已取消


class CleaningTaskPriority(str, Enum):
    """清洁任务优先级枚举"""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    URGENT = "urgent"
    CRITICAL = "critical"


class WasteDetection(BaseModel):
    """垃圾检测结果模型"""
    detection_id: str = Field(..., description="检测ID")
    waste_type: WasteType = Field(..., description="垃圾类型")
    confidence: float = Field(..., ge=0, le=1, description="置信度")
    bounding_box: List[float] = Field(..., description="边界框 [x1, y1, x2, y2]")
    area: float = Field(..., description="检测区域面积")
    location: Tuple[float, float] = Field(..., description="中心位置坐标")
    timestamp: datetime = Field(..., description="检测时间")
    camera_id: str = Field(..., description="摄像头ID")
    zone_id: Optional[str] = Field(None, description="区域ID")
    
    @field_validator('bounding_box')
    @classmethod
    def validate_bbox(cls, v: List[float]) -> List[float]:
        if len(v) != 4:
            raise ValueError('边界框必须包含4个值: [x1, y1, x2, y2]')
        return v
    
    def get_center(self) -> Tuple[float, float]:
        """获取中心点坐标"""
        x1, y1, x2, y2 = self.bounding_box
        return ((x1 + x2) / 2, (y1 + y2) / 2)
    
    def get_area(self) -> float:
        """计算检测区域面积"""
        x1, y1, x2, y2 = self.bounding_box
        return (x2 - x1) * (y2 - y1)
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "detection_id": "waste_det_123",
                "waste_type": "plastic",
                "confidence": 0.85,
                "bounding_box": [100, 100, 200, 150],
                "area": 5000,
                "location": [150, 125],
                "timestamp": "2024-01-01T12:00:00Z",
                "camera_id": "cam_001",
                "zone_id": "classroom_101"
            }
        }}


class WasteAnalysisResult(BaseModel):
    """垃圾分析结果模型"""
    analysis_id: str = Field(..., description="分析ID")
    camera_id: str = Field(..., description="摄像头ID")
    timestamp: datetime = Field(..., description="分析时间")
    detections: List[WasteDetection] = Field(..., description="检测结果列表")
    total_waste_count: int = Field(..., description="垃圾总数")
    waste_type_distribution: Dict[str, int] = Field(..., description="垃圾类型分布")
    total_waste_area: float = Field(..., description="垃圾总面积")
    processing_time: float = Field(..., description="处理时间(秒)")
    model_info: Dict[str, Any] = Field({}, description="模型信息")
    
    model_config = {"json_schema_extra": {
            "example": {
                "analysis_id": "waste_analysis_456",
                "camera_id": "cam_001",
                "timestamp": "2024-01-01T12:00:00Z",
                "detections": [],
                "total_waste_count": 5,
                "waste_type_distribution": {
                "plastic": 2,
                "paper": 2,
                "organic": 1
                },
                "total_waste_area": 15000,
                "processing_time": 0.3,
                "model_info": {
                "model_name": "YOLOv8 Waste Detection",
                "version": "1.0"
                }}
        }
    }


class CleanlinessAssessment(BaseModel):
    """清洁度评估模型"""
    assessment_id: str = Field(..., description="评估ID")
    camera_id: str = Field(..., description="摄像头ID")
    zone_id: str = Field(..., description="区域ID")
    timestamp: datetime = Field(..., description="评估时间")
    cleanliness_score: float = Field(..., ge=0, le=100, description="清洁度评分")
    cleanliness_level: CleanlinessLevel = Field(..., description="清洁度级别")
    assessment_factors: Dict[str, float] = Field(..., description="评估因子")
    detected_issues: List[Dict[str, Any]] = Field([], description="检测到的问题")
    recommendations: List[str] = Field([], description="改进建议")
    comparison_data: Optional[Dict[str, Any]] = Field(None, description="对比数据")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "assessment_id": "clean_assess_789",
                "camera_id": "cam_001",
                "zone_id": "classroom_101",
                "timestamp": "2024-01-01T12:00:00Z",
                "cleanliness_score": 85.5,
                "cleanliness_level": "good",
                "assessment_factors": {
                "waste_presence": 0.1,
                "surface_cleanliness": 0.9,
                "organization": 0.8,
                "maintenance": 0.85
                },
                "detected_issues": [
                    {
                "type": "litter",
                "severity": "low",
                "location": [150, 200]
                    }
                ],
                "recommendations": [
                "增加垃圾桶数量",
                "定期清理地面"
                ]
            }
        }}


class HygieneIssue(BaseModel):
    """卫生问题模型"""
    issue_id: str = Field(..., description="问题ID")
    issue_type: HygieneIssueType = Field(..., description="问题类型")
    severity: str = Field(..., description="严重程度")
    description: str = Field(..., description="问题描述")
    location: Tuple[float, float] = Field(..., description="问题位置")
    bounding_box: Optional[List[float]] = Field(None, description="问题区域")
    confidence: float = Field(..., ge=0, le=1, description="检测置信度")
    camera_id: str = Field(..., description="摄像头ID")
    zone_id: str = Field(..., description="区域ID")
    detected_at: datetime = Field(..., description="检测时间")
    resolved_at: Optional[datetime] = Field(None, description="解决时间")
    is_resolved: bool = Field(False, description="是否已解决")
    resolution_notes: Optional[str] = Field(None, description="解决备注")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "issue_id": "hygiene_issue_001",
                "issue_type": "litter",
                "severity": "medium",
                "description": "地面有纸屑和塑料瓶",
                "location": [320, 240],
                "bounding_box": [300, 220, 340, 260],
                "confidence": 0.92,
                "camera_id": "cam_001",
                "zone_id": "classroom_101",
                "detected_at": "2024-01-01T12:00:00Z",
                "is_resolved": False
            }
        }}


class CleaningTask(BaseModel):
    """清洁任务模型"""
    task_id: str = Field(..., description="任务ID")
    task_type: str = Field(..., description="任务类型")
    title: str = Field(..., description="任务标题")
    description: str = Field(..., description="任务描述")
    priority: CleaningTaskPriority = Field(..., description="优先级")
    status: CleaningTaskStatus = Field(..., description="任务状态")
    zone_id: str = Field(..., description="区域ID")
    camera_id: str = Field(..., description="摄像头ID")
    related_issues: List[str] = Field([], description="相关问题ID列表")
    assigned_to: Optional[str] = Field(None, description="分配给")
    estimated_duration: Optional[int] = Field(None, description="预估时长(分钟)")
    actual_duration: Optional[int] = Field(None, description="实际时长(分钟)")
    created_at: datetime = Field(..., description="创建时间")
    assigned_at: Optional[datetime] = Field(None, description="分配时间")
    started_at: Optional[datetime] = Field(None, description="开始时间")
    completed_at: Optional[datetime] = Field(None, description="完成时间")
    verified_at: Optional[datetime] = Field(None, description="验证时间")
    before_images: List[str] = Field([], description="清洁前图片")
    after_images: List[str] = Field([], description="清洁后图片")
    notes: Optional[str] = Field(None, description="备注")
    
    model_config = {"json_schema_extra": {
            "example": {
                "task_id": "clean_task_001",
                "task_type": "routine_cleaning",
                "title": "教室101日常清洁",
                "description": "清理地面垃圾，擦拭桌椅",
                "priority": "medium",
                "status": "pending",
                "zone_id": "classroom_101",
                "camera_id": "cam_001",
                "related_issues": ["hygiene_issue_001"],
                "estimated_duration": 30,
                "created_at": "2024-01-01T12:00:00Z"
        }
    }
        }


class CleaningEfficiencyMetrics(BaseModel):
    """清洁效率指标模型"""
    metrics_id: str = Field(..., description="指标ID")
    cleaner_id: Optional[str] = Field(None, description="清洁员ID")
    zone_id: str = Field(..., description="区域ID")
    task_id: str = Field(..., description="任务ID")
    start_time: datetime = Field(..., description="开始时间")
    end_time: datetime = Field(..., description="结束时间")
    duration_minutes: int = Field(..., description="持续时间(分钟)")
    area_cleaned: float = Field(..., description="清洁面积(平方米)")
    cleaning_speed: float = Field(..., description="清洁速度(平方米/分钟)")
    quality_score: float = Field(..., ge=0, le=100, description="质量评分")
    before_cleanliness_score: float = Field(..., description="清洁前评分")
    after_cleanliness_score: float = Field(..., description="清洁后评分")
    improvement_score: float = Field(..., description="改善评分")
    efficiency_rating: str = Field(..., description="效率评级")
    issues_resolved: int = Field(0, description="解决的问题数量")
    tools_used: List[str] = Field([], description="使用的工具")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "metrics_id": "efficiency_001",
                "cleaner_id": "cleaner_001",
                "zone_id": "classroom_101",
                "task_id": "clean_task_001",
                "start_time": "2024-01-01T14:00:00Z",
                "end_time": "2024-01-01T14:30:00Z",
                "duration_minutes": 30,
                "area_cleaned": 50.0,
                "cleaning_speed": 1.67,
                "quality_score": 88.5,
                "before_cleanliness_score": 65.0,
                "after_cleanliness_score": 88.5,
                "improvement_score": 23.5,
                "efficiency_rating": "good",
                "issues_resolved": 3,
                "tools_used": ["vacuum", "mop", "disinfectant"]
            }
        }}


class HygieneZone(BaseModel):
    """卫生区域模型"""
    zone_id: str = Field(..., description="区域ID")
    zone_name: str = Field(..., description="区域名称")
    zone_type: str = Field(..., description="区域类型")
    coordinates: List[Tuple[float, float]] = Field(..., description="区域坐标")
    area_sqm: float = Field(..., description="区域面积(平方米)")
    cleaning_frequency: str = Field(..., description="清洁频率")
    cleanliness_standard: float = Field(..., description="清洁标准评分")
    current_cleanliness: float = Field(0, description="当前清洁度")
    last_cleaned: Optional[datetime] = Field(None, description="上次清洁时间")
    next_cleaning: Optional[datetime] = Field(None, description="下次清洁时间")
    assigned_cleaner: Optional[str] = Field(None, description="负责清洁员")
    special_requirements: List[str] = Field([], description="特殊要求")
    
    model_config = {"json_schema_extra": {
            "example": {
                "zone_id": "classroom_101",
                "zone_name": "教室101",
                "zone_type": "classroom",
                "coordinates": [[0, 0], [100, 0], [100, 80], [0, 80]],
                "area_sqm": 80.0,
                "cleaning_frequency": "daily",
                "cleanliness_standard": 85.0,
                "current_cleanliness": 78.5,
                "last_cleaned": "2024-01-01T08:00:00Z",
                "next_cleaning": "2024-01-02T08:00:00Z",
                "assigned_cleaner": "cleaner_001",
                "special_requirements": ["disinfection", "floor_mopping"]
        }
    }
        }


class WasteDetectionConfig(BaseModel):
    """垃圾检测配置模型"""
    model_type: str = Field("yolov8", description="模型类型")
    confidence_threshold: float = Field(0.5, ge=0, le=1, description="置信度阈值")
    nms_threshold: float = Field(0.4, ge=0, le=1, description="NMS阈值")
    max_detections: int = Field(100, ge=1, description="最大检测数量")
    input_size: Tuple[int, int] = Field((640, 640), description="输入尺寸")
    waste_types: List[WasteType] = Field(list(WasteType), description="检测的垃圾类型")
    min_area_threshold: float = Field(100, description="最小面积阈值")
    enable_tracking: bool = Field(True, description="是否启用跟踪")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "model_type": "yolov8",
                "confidence_threshold": 0.6,
                "nms_threshold": 0.4,
                "max_detections": 50,
                "input_size": [640, 640],
                "waste_types": ["plastic", "paper", "organic"],
                "min_area_threshold": 200,
                "enable_tracking": True
            }
        }}


class CleanlinessConfig(BaseModel):
    """清洁度评估配置模型"""
    assessment_method: str = Field("comprehensive", description="评估方法")
    weight_factors: Dict[str, float] = Field({
                "waste_presence": 0.3,
                "surface_cleanliness": 0.25,
                "organization": 0.2,
                "maintenance": 0.15,
                "lighting": 0.1
    }, description="权重因子")
    score_thresholds: Dict[str, Tuple[float, float]] = Field({
                "excellent": (90, 100),
                "good": (80, 89),
                "fair": (70, 79),
                "poor": (60, 69),
                "very_poor": (0, 59)
    }, description="评分阈值")
    enable_comparison: bool = Field(True, description="是否启用对比分析")
    comparison_period_days: int = Field(7, description="对比周期(天)")
    
    model_config = {"json_schema_extra": {
            "example": {
                "assessment_method": "comprehensive",
                "weight_factors": {
                "waste_presence": 0.3,
                "surface_cleanliness": 0.25,
                "organization": 0.2,
                "maintenance": 0.15,
                "lighting": 0.1
                },
                "enable_comparison": True,
                "comparison_period_days": 7
            }}
        }


class HygieneReport(BaseModel):
    """卫生报告模型"""
    report_id: str = Field(..., description="报告ID")
    report_type: str = Field(..., description="报告类型")
    title: str = Field(..., description="报告标题")
    period_start: datetime = Field(..., description="统计开始时间")
    period_end: datetime = Field(..., description="统计结束时间")
    zones_covered: List[str] = Field(..., description="覆盖区域")
    summary: Dict[str, Any] = Field(..., description="总结信息")
    detailed_data: Dict[str, Any] = Field(..., description="详细数据")
    trends: Dict[str, Any] = Field(..., description="趋势分析")
    recommendations: List[str] = Field(..., description="建议")
    generated_at: datetime = Field(..., description="生成时间")
    generated_by: str = Field(..., description="生成者")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "report_id": "hygiene_report_001",
                "report_type": "weekly_summary",
                "title": "第1周卫生状况报告",
                "period_start": "2024-01-01T00:00:00Z",
                "period_end": "2024-01-07T23:59:59Z",
                "zones_covered": ["classroom_101", "classroom_102", "hallway_1"],
                "summary": {
                "average_cleanliness": 82.5,
                "total_issues": 15,
                "resolved_issues": 12,
                "cleaning_tasks": 25
                },
                "detailed_data": {}},
                "trends": {
                "cleanliness_trend": "improving",
                "issue_frequency": "decreasing"
                },
                "recommendations": [
                "增加垃圾桶数量",
                "提高清洁频率"
                ],
                "generated_at": "2024-01-08T09:00:00Z",
                "generated_by": "system"
            }
        }